package cn.wsn2018.tools.exceptionHandler;

import cn.wsn2018.tools.common.CommonValue;
import cn.wsn2018.tools.dao.UserDao;
import cn.wsn2018.tools.model.Log.ErrorLogInfo;
import cn.wsn2018.tools.model.User;
import cn.wsn2018.tools.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;

/**
 * @program: tools
 * @description
 * @author: songDaisong
 * @create: 2019-12-07 18:34
 **/

@RestControllerAdvice
public class GlobalDefaultException {

    @Autowired
    private UserDao userDao;

    @ExceptionHandler(value = Exception.class)
    public void catchException(Exception e){

        //获取Threadlcoal里面的变量
        ThreadLocal<String> localUserName = ThreadUtil.getThreadLocalUserName();

        //默认值，如果能获取到则替换
        String ipAddress ="127.0.0.1";
        String machineName="localhost";
        String operatorType=ServletUtil.operatorTypeMap.get(CommonValue.LOGIN_MODULE);//默认请求系统登录模块接口
        String name = localUserName.get();
        User user=null;
        String moduleName=CommonValue.LOGIN_MODULE;

        if (StringUtil.isEmptyString(name)){
            //从Threadlocal中可以获取到用户名
            name="100001";
        }else{
            //name不为空时，获取用户信息
            user = userDao.getUserByName(name);
        }

        try {
            //获取ip和机器码
            ipAddress =InetAddress.getLocalHost().getHostAddress();
            machineName = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        }finally {

            if (user!=null){
                //判断用户角色
                String role = user.getRole();
                if (CommonValue.ROLE_ADMIN.equals(role)){
                    //管理员
                    operatorType=ServletUtil.operatorTypeMap.get(CommonValue.ADMIN_MODULE);
                    moduleName= CommonValue.ADMIN_MODULE;
                }else if(CommonValue.ROLE_SYS_AUDITOR.equals(role)){
                    //系统审计员
                    operatorType=ServletUtil.operatorTypeMap.get(CommonValue.SYS_AUDITOR_MODULE);
                    moduleName= CommonValue.SYS_AUDITOR_MODULE;
                }else if(CommonValue.ROLE_AUDITOR.equals(role)){
                    //业务审计员
                    operatorType=ServletUtil.operatorTypeMap.get(CommonValue.ROLE_AUDITOR);
                    moduleName=CommonValue.AUDITOR_MODULE;
                }else if(CommonValue.ROLE_OPERATOR.equals(role)){
                    //操作员
                    operatorType=ServletUtil.operatorTypeMap.get(CommonValue.OPERATOR_MODULE);
                    moduleName= CommonValue.OPERATOR_MODULE;
                }
            }

            ErrorLogInfo errorLogInfo = new ErrorLogInfo();
            //系统日志
            errorLogInfo.setType(CommonValue.LOG_TYPE_SYS);
            errorLogInfo.setCreateTime( DateUtil.dateToString(new Date()));

            //将 e.printStackTrace()的信息保存到字符串
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            String msg=sw.toString();

            //将错误信息根据换行分割
            String[] strings = msg.split("\\n");
            if (strings.length>=2){
                msg=strings[0]+";"+strings[1];
                if (strings[1].toLowerCase().contains("login")){
                    //错误信息包含login表示是发生在与登录有关的地方
                     moduleName=CommonValue.LOGIN_MODULE;
                     operatorType=ServletUtil.operatorTypeMap.get(CommonValue.LOGIN_MODULE);
                }
            }else {
                msg=e.getClass().getName();
            }

            //控制台打印输出的异常信息
//            int j=0;
//            System.out.println(strings.length);
//            for (String s:strings){
//                j++;
//                System.out.println("["+j+"]"+s);
//            }

            //存放错误信息
            errorLogInfo.setErrorRunningInfo(msg);
            //模块名
            errorLogInfo.setModuleName(moduleName);
            //用户名
            errorLogInfo.setUsername(name);
            //机器名
            errorLogInfo.setMachineName(machineName);
            //ip地址
            errorLogInfo.setIpAddress(ipAddress);
            //操作类型--跟用户名对应的角色有关
            errorLogInfo.setOperatorType(operatorType);
            //记录错误日志
            LogUtil.produceErrorLogs(errorLogInfo);

            //防止内存泄露
            localUserName.remove();
        }




    }
}
